﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using DotNetNuke.Common;
using DotNetNuke.Entities;
using DotNetNuke.Entities.Modules;
using ShopSpace.Core;
using ShopSpace.Core.Repositories;
using ShopSpace.Infrastructure.UI;
using DotNetNuke.UI.Skins;
using DotNetNuke.UI.Skins.Controls;
using DotNetNuke.Services.Log.EventLog;

namespace ShopSpace.UI.DotNetNukeModules
{
	public class ModuleControlBase : PortalModuleBase
	{
		#region Private Fields

		private IPersonRepository personRepository;
		private IProjectRepository projectRepository;
		private IProjectPersonRepository projectPersonRepository;
		private IWorkItemRepository workItemRepository;
		private IWorkItemCategoryRepository workItemCategoryRepository;
		private IWorkItemStatusRepository workItemStatusRepository;
		private IMilestoneRepository milestoneRepository;
		
		#endregion

		#region Protected Properties

		protected IPersonRepository PersonRepository
		{
			get
			{
				if (this.personRepository == null)
				{
					this.personRepository = ServiceLocator.Get<IPersonRepository>();
				}
				return this.personRepository;
			}
		}

		protected IProjectRepository ProjectRepository
		{
			get
			{
				if (this.projectRepository == null)
				{
					this.projectRepository = ServiceLocator.Get<IProjectRepository>();
				}
				return this.projectRepository;
			}
		}

		protected IProjectPersonRepository ProjectPersonRepository
		{
			get
			{
				if ( this.projectPersonRepository == null )
				{
					this.projectPersonRepository = ServiceLocator.Get<IProjectPersonRepository>();
				}
				return this.projectPersonRepository;
			}
		}

		protected IWorkItemRepository WorkItemRepository
		{
			get
			{
				if (this.workItemRepository == null)
				{
					this.workItemRepository = ServiceLocator.Get<IWorkItemRepository>();
				}
				return this.workItemRepository;
			}
		}

		protected IWorkItemCategoryRepository WorkItemCategoryRepository
		{
			get
			{
				if (this.workItemCategoryRepository == null)
				{
					this.workItemCategoryRepository = ServiceLocator.Get<IWorkItemCategoryRepository>();
				}
				return this.workItemCategoryRepository;
			}
		}

		protected IWorkItemStatusRepository WorkItemStatusRepository
		{
			get
			{
				if (this.workItemStatusRepository == null)
				{
					this.workItemStatusRepository = ServiceLocator.Get<IWorkItemStatusRepository>();
				}
				return this.workItemStatusRepository;
			}
		}

		protected IMilestoneRepository MilestoneRepository
		{
			get
			{
				if (this.milestoneRepository == null)
				{
					this.milestoneRepository = ServiceLocator.Get<IMilestoneRepository>();
				}
				return this.milestoneRepository;
			}
		}

		protected Person Person
		{
			get;
			private set;
		}

		protected UserState UserState
		{
			get;
			private set;
		}

		#endregion

		#region Event Handlers

		protected override void OnInit(EventArgs e)
		{
			try
			{
				this.InitPerson();
				this.InitUserState();
			}
			catch (Exception ex)
			{
				this.HandleException(ex);
			}
			base.OnInit(e);
		}

		protected override void OnLoad(EventArgs e)
		{
			this.ShowUserMessages();
			base.OnLoad(e);
		}

		#endregion

		#region Protected Methods

		protected void HandleException(Exception ex)
		{
			if (ex is System.Threading.ThreadAbortException)
			{
				return;
			}
			if (ex is ApplicationException)
			{
				Skin.AddModuleMessage(this, ex.Message, DotNetNuke.UI.Skins.Controls.ModuleMessage.ModuleMessageType.YellowWarning);
			}
			else
			{
#if DEBUG
				Skin.AddModuleMessage(this, ex.ToString(), DotNetNuke.UI.Skins.Controls.ModuleMessage.ModuleMessageType.RedError);
#else
				Skin.AddModuleMessage(this, "Error Occurred. Please contact the site administrator.", DotNetNuke.UI.Skins.Controls.ModuleMessage.ModuleMessageType.RedError);
				this.LogException(ex);
#endif

			}
		}

		protected void LogException(Exception ex)
		{
			try
			{
				LogInfo logInfo = new LogInfo(ex.ToString());
				logInfo.LogCreateDate = DateTime.Now;
				logInfo.LogPortalID = this.PortalId;
				logInfo.LogUserID = this.UserId;
				logInfo.LogUserName = this.UserInfo.Username;
				LoggingProvider.Instance().AddLog(logInfo);
			}
			catch
			{
				//TODO
			}
		}

		protected virtual void ShowUserMessages()
		{
			foreach ( ModuleMessage msg in UserState.GetMessages(this.ModuleId) )
			{
				Skin.AddModuleMessage(this, msg.Text, msg.IconType);
			}
			UserState.ClearMessages(this.ModuleId);
		}

		#endregion

		#region Private Methods

		private void InitPerson()
		{
			this.Person = this.PersonRepository.GetByUsername(this.PortalId, this.UserInfo.Username);
		}

		private void InitUserState()
		{
			this.UserState = new UserState(UserId.ToString() + "." + this.PortalId.ToString());
		}

		#endregion
	}
}